<?php
/**
 * 
 * Контроллер пунктов меню
 * @author andrew
 *
 */
class Navigation_MenuitemController extends Zend_Controller_Action {
	/**
	 * 
	 * Список пунктов меню
	 */		
	public function indexAction() {
		$form = new Navigation_Form_Tools();
		$form->setAction($this->view->url(array(),'navigation_menuitem_index'));
		
		$menus = Doctrine_Core::getTable('Navigation_Model_Menu')->findAll();
		
		$populate = array(
			'0' => $this->view->translate('--All--')
		);
		
		foreach ($menus as $menu) {
			$populate[$menu->id] = $menu->name;
		}
		
		$menu_id = $form->getElement('menu_id');
		$menu_id->addMultiOptions($populate);
		
		if($this->_request->isPost() && $form->isValid($this->_request->getPost())) {
			$values = $form->getValues();
			
			if($values['menu_id'] > 0) {
				$query = Doctrine_Query::create()
					 ->from('Navigation_Model_Menuitem')
					 ->where('menu_id = ?', $values['menu_id'])
					 ->addOrderBy('lft ASC')
					 ->addOrderBy('ordering ASC');
			} else {
				$query = Doctrine_Query::create()
					 ->from('Navigation_Model_Menuitem')
					 ->orderBy('menu_id ASC')
					 ->addOrderBy('lft ASC')
					 ->addOrderBy('ordering ASC');
			}
		} else {
			$query = Doctrine_Query::create()
					 ->from('Navigation_Model_Menuitem')
					 ->orderBy('menu_id ASC')
					 ->addOrderBy('lft ASC')
					 ->addOrderBy('ordering ASC');
		}
		
		$menuItems = array();
		
		$treeObject = Doctrine_Core::getTable('Navigation_Model_Menuitem')->getTree();
		$treeObject->setBaseQuery($query);
		$rootColumnName = $treeObject->getAttribute('rootColumnName');
		foreach ($treeObject->fetchRoots() as $root) {
			$options = array(
				'root_id' => $root->$rootColumnName
			);
			foreach ($treeObject->fetchTree($options) as $node) {
				$menuItems[$node->id]['name'] = str_repeat('..', $node->level) . $node->Translation[$this->view->LANG]->label;
				$menuItems[$node->id]['id'] = $node->id;
				$node->target ? $menuItems[$node->id]['target'] = '_self' : $menuItems[$node->id]['target'] = '_blank';
				$menuItems[$node->id]['menu'] = $node->Navigation_Model_Menu->name;
				$menuItems[$node->id]['uri'] = $node->uri;
				$menuItems[$node->id]['published'] = $node->published;
			}
		}
		$treeObject->resetBaseQuery();
		
		$this->view->form = $form;
		$this->view->menuItems = $menuItems;
		
	}
	
	/**
	 * 
	 * Редактирование ссылки
	 * @throws Zend_Controller_Action_Exception
	 */
	public function updateAction() {
		$id = $this->_request->getParam('id',0);
		
		$menuItem = Doctrine_Core::getTable('Navigation_Model_Menuitem')->find($id);
		
		if(!$id || !$menuItem)
			throw new Zend_Controller_Action_Exception('Menu item not found!', 404);
		
		
		$form = new Navigation_Form_Menuitem();
		$form->setAction($this->view->url(array('id' => $id),'navigation_menuitem_update'));
		
		$populate = array();
		
		$locales = Zend_Controller_Front::getInstance()->getParam('bootstrap')->getOption('locales');
		
		foreach ($locales as $lang=>$value) {
			$populate['name'][$lang] = $menuItem->Translation[$lang]->label;
			$populate['title'][$lang] = $menuItem->Translation[$lang]->title;
		}
		
		$populate['target'] = $menuItem->target;
		$populate['menu_id'] = $menuItem->menu_id;
		$populate['published'] = $menuItem->published;
		$populate['uri'] = $menuItem->uri;
		$menuItem->getNode()->getParent() ? $populate['parent'] = $menuItem->getNode()->getParent()->id : $populate['parent'] = 0;
		
		//получаем список меню
		$menu = Doctrine_Query::create()
				->from('Navigation_Model_Menu')
				->execute();
				
		$menu_array = array();
		foreach ($menu as $m) {
			$menu_array[$m->id] = $m->name;
		}
		//заносим меню в элемент
		$menu_element = $form->getElement('menu_id');
		$menu_element->addMultiOptions($menu_array);
		
		//получаем древо предков
		$query = Doctrine_Query::create()
				 ->from('Navigation_Model_Menuitem')
				 ->where('id <> ?', $id)
				 ->orderBy('id ASC');
				 
		$treeObject = Doctrine_Core::getTable('Navigation_Model_Menuitem')->getTree();
		$treeObject->setBaseQuery($query);
		
		$rootColumnName = $treeObject->getAttribute('rootColumnName');
		
		$items = array('0' => $this->view->translate('New parent'));
		
		foreach ($treeObject->fetchRoots() as $root) {
		  $options = array(
		      'root_id' => $root->$rootColumnName
		  );
		  foreach($treeObject->fetchTree($options) as $key=>$node) {
		   		$items[$node->id] = str_repeat('-', 2*$node->level) . $node->Translation[$this->view->LANG]->label;
		  }
		}
		$treeObject->resetBaseQuery();
		//заносим древо в элемент формы
		$parent_element = $form->getElement('parent');
		$parent_element->addMultiOptions($items);
		
		//получаем и заносим карту сайта в элемент sitemap
		$sitemap_container = Zend_Registry::get('container');
		
		$menu_parse = array();
		
		$this->_parseContainer($sitemap_container, $menu_parse, 0);
		
		$sitemape_element = $form->getElement('sitemap');
		$sitemape_element->addMultiOptions($menu_parse);
		
		$this->view->form = $form;
		
		if($this->_request->isPost() && $form->isValid($this->_request->getPost())) {
			$values = $form->getValues();
			
			if($values['ref'] == 'sitemap') {
				$menuItem->uri = $values['sitemap'];
			} else {
				$menuItem->uri = $values['uri'];
			}
			
			foreach ($values['name'] as $lang=>$value) {
				$menuItem->Translation[$lang]->label = $value;	
			}
			foreach ($values['title'] as $lang=>$value) {
				$menuItem->Translation[$lang]->title = $value;	
			}
			$menuItem->target = $values['target'];
			$menuItem->published = $values['published'];
			$menuItem->menu_id = $values['menu_id'];
			
			if(($menuItem->getNode()->getParent() && $menuItem->getNode()->getParent()->id == $values['parent']) || (!$menuItem->getNode()->getParent() && $values['parent'] == 0)) {
				$menuItem->save();
			} elseif($menuItem->getNode()->getParent() && $values['parent'] == 0) {
				$menuItem->parent_id = null;
				//определяем максимальный ordering
				$max_ordering = Doctrine_Query::create()
							    ->select('MAX(ordering) as max_ordering')
							    ->from('Navigation_Model_Menuitem')
							    ->where('menu_id = ?', $values['menu_id'])
							    ->andWhere('level = ?', 0)
							    ->andWhere('id <> ?', $menuItem->id)
							    ->execute();
				if($max_ordering[0]->max_ordering + 1 != $menuItem->ordering) {
					$menuItem->ordering = $max_ordering[0]->max_ordering + 1;
				} else {
					$menuItem->ordering = 1;
				}
				$menuItem->save();
				
				$maxRootId = Doctrine_Query::create()
							 ->select('MAX(root_id) as maxrootid')
							 ->from('Navigation_Model_Menuitem')
							 ->where('level = ?',0)
							 ->execute();
				
				$menuItem->getNode()->makeRoot($maxRootId[0]->maxrootid + 1);
				
			} elseif($values['parent'] > 0) {
				$parent = Doctrine_Core::getTable('Navigation_Model_Menuitem')->find($values['parent']);
				
				$menuItem->parent_id = $values['parent'];
				
				if(!$parent->getNode()->hasChildren()) {
					$menuItem->ordering = 1;
				} else {
					$children = $parent->getNode()->getDescendants(1);
					
					$first_children_id = $children[0]->id;
					$last_children_id = $children[$children->count()-1]->id;
					
					$maxordering = Doctrine_Query::create()
								   ->select('MAX(ordering) as maxordering')
								   ->from('Navigation_Model_Menuitem')
								   ->where('id >= ?', $first_children_id)
								   ->andWhere('id <= ?', $last_children_id)
								   ->execute();
								   
					if($max_ordering[0]->max_ordering + 1 != $menuItem->ordering) {
						$menuItem->ordering = $max_ordering[0]->max_ordering + 1;
					} else {
						$menuItem->ordering = 1;
					}
				}
				
				
				$menuItem->getNode()->moveAsLastChildOf($parent);
			}
			
			$this->_helper->getHelper('FlashMessenger')
					->addMessage($this->view->translate('Menu item has been save successfully!'));
			return $this->_redirect($this->view->url(array(), 'navigation_menuitem_index'));
		} else {
			$form->populate($populate);
		}
	}
	
	/**
	 * Создание пункта меню
	 */
	public function createAction() {
		
		$menu_id = $this->_request->getParam('menu');
		
		//получаем список меню
		$menu = Doctrine_Query::create()
				->from('Navigation_Model_Menu')
				->execute();
				
		if($menu->count() == 0) {
			$this->_helper->getHelper('FlashMessenger')
					->addMessage($this->view->translate('Create first menu!'));
			return $this->_redirect($this->view->url(array(), 'navigation_menu_index'));
		}
		
		$form = new Navigation_Form_Menuitem();
		$form->setAction($this->view->url(array(),'navigation_menuitem_create'));
		
		//получаем древо предков
		$treeObject = Doctrine_Core::getTable('Navigation_Model_Menuitem')->getTree();

		$rootColumnName = $treeObject->getAttribute('rootColumnName');
		
		$items = array('0' => $this->view->translate('New parent'));
		
		foreach ($treeObject->fetchRoots() as $root) {
		  $options = array(
		      'root_id' => $root->$rootColumnName
		  );
		  foreach($treeObject->fetchTree($options) as $key=>$node) {
		   		$items[$node->id] = str_repeat('-', 2*$node->level) . $node->Translation[$this->view->LANG]->label;
		  }
		}
		//заносим древо в элемент формы
		$parent_element = $form->getElement('parent');
		$parent_element->addMultiOptions($items);
		$parent_element->setValue(0);
		
		
		$menu_array = array();
		foreach ($menu as $m) {
			$menu_array[$m->id] = $m->name;
		}
		//заносим меню в элемент
		$menu_element = $form->getElement('menu_id');
		$menu_element->addMultiOptions($menu_array);
		
		//получаем и заносим карту сайта в элемент sitemap
		$sitemap_container = Zend_Registry::get('container');
		
		$menu_parse = array();
		
		$this->_parseContainer($sitemap_container, $menu_parse, 0);
		
		$sitemape_element = $form->getElement('sitemap');
		$sitemape_element->addMultiOptions($menu_parse);
		
		if($this->_request->isPost() && $form->isValid($this->_request->getPost())) {
			$values = $form->getValues();
			
			$modelItem = new Navigation_Model_Menuitem();
			
			if($values['ref'] == 'sitemap') {
				$modelItem->uri = $values['sitemap'];
			} else {
				$modelItem->uri = $values['uri'];
			}
			
			foreach ($values['name'] as $lang=>$value) {
				$modelItem->Translation[$lang]->label = $value;	
			}
			foreach ($values['title'] as $lang=>$value) {
				$modelItem->Translation[$lang]->title = $value;	
			}
			$modelItem->target = $values['target'];
			$modelItem->published = $values['published'];
			$modelItem->menu_id = $values['menu_id'];
			
			if($values['parent'] == 0) {
				//определяем максимальный ordering
				$max_ordering = Doctrine_Query::create()
							    ->select('MAX(ordering) as max_ordering')
							    ->from('Navigation_Model_Menuitem')
							    ->where('menu_id = ?', $values['menu_id'])
							    ->andWhere('level = ?', 0)
							    ->execute();
				if($max_ordering->count()) {
					$modelItem->ordering = $max_ordering[0]->max_ordering + 1;
				} else {
					$modelItem->ordering = 1;
				}
				$modelItem->parent_id = null;
				$modelItem->save();
				
				$treeObject = Doctrine_Core::getTable('Navigation_Model_Menuitem')->getTree();
				$treeObject->createRoot($modelItem);
			} else {
				$modelItem->parent_id = $values['parent'];
				$parent = Doctrine_Core::getTable('Navigation_Model_Menuitem')->find($values['parent']);
				
				if(!$parent->getNode()->hasChildren()) {
					$modelItem->ordering = 1;
				} else {
					$children = $parent->getNode()->getDescendants(1);
					
					$first_children_id = $children[0]->id;
					$last_children_id = $children[$children->count()-1]->id;
					
					$maxordering = Doctrine_Query::create()
								   ->select('MAX(ordering) as maxordering')
								   ->from('Navigation_Model_Menuitem')
								   ->where('id >= ?', $first_children_id)
								   ->andWhere('id <= ?', $last_children_id)
								   ->execute();
								   
					$modelItem->ordering = $maxordering[0]->maxordering + 1;
				}
				
				$modelItem->getNode()->insertAsLastChildOf($parent);
			}
			
			$this->_helper->getHelper('FlashMessenger')
					->addMessage($this->view->translate('Menu item created success!'));
			return $this->_redirect($this->view->url(array(), 'navigation_menuitem_index'));
		}
		
		$this->view->form = $form;
	}
	
	/**
	 * 
	 * Удаление ссылки из меню
	 */
	public function deleteAction() {
		$id = $this->_request->getParam('id', 0);
		
		$menuItem = Doctrine_Core::getTable('Navigation_Model_Menuitem')->find($id);
		
		$menuItem->getNode()->delete();
		
		$this->_helper->getHelper('FlashMessenger')
					->addMessage($this->view->translate('Menu item has been delete successfully!'));
		return $this->_redirect($this->view->url(array(), 'navigation_menuitem_index'));
	}
	
	/**
	 * 
	 * Сортировка
	 * @throws Zend_Controller_Action_Exception
	 */
	public function orderingAction() {
		$id = $this->_request->getParam('id',0);
		
		$menuItem = Doctrine_Core::getTable('Navigation_Model_Menuitem')->find($id);
		
		if(!$id || !$menuItem)
			throw new Zend_Controller_Action_Exception('Menu item not found!',404);
			
		$diff = $this->_request->getParam('diff','1');
		
		$maxordering = Doctrine_Query::create()
						   ->select('MAX(ordering) as maxordering')
						   ->from('Navigation_Model_Menuitem')
						   ->where('menu_id = ?', $menuItem->menu_id)
						   ->andWhere('level = ?', $menuItem->level)
						   ->execute();
						   
		if($maxordering && $maxordering->count() == 1) {
			$maxordering = $maxordering[0]->maxordering;
		} else {
			$maxordering = 1;
		}
		
		if($menuItem->getNode()->isRoot()){
			if($diff == '1' && $menuItem->ordering == 1) {
				return $this->_redirect($this->view->url(array(), 'navigation_menuitem_index'));
			}
			if($diff == '-1' && $menuItem->ordering == $maxordering) {
				return $this->_redirect($this->view->url(array(), 'navigation_menuitem_index'));
			}
		}
			
		
		if($diff == '1') {				
			if($menuItem->getNode()->isRoot()) {
				$prevNode = Doctrine_Query::create()
						 ->from('Navigation_Model_Menuitem')
						 ->where('menu_id = ?', $menuItem->menu_id)
						 ->andWhere('level = 0')
						 ->andWhere('ordering = ?', $menuItem->ordering - 1)
						 ->execute();

				$ordering = $menuItem->ordering;
				$menuItem->ordering = $prevNode[0]->ordering;
				$menuItem->save();
				$prevNode[0]->ordering = $ordering;
				$prevNode[0]->save();
			} else {
				$prevSibling = $menuItem->getNode()->getPrevSibling();
				
				if($prevSibling) {
					$menuItem->getNode()->moveAsPrevSiblingOf($prevSibling);
				}
			}
		}
		
		if($diff == '-1') {
							
			if($menuItem->getNode()->isRoot()) {
				$prevNode = Doctrine_Query::create()
						 ->from('Navigation_Model_Menuitem')
						 ->where('menu_id = ?', $menuItem->menu_id)
						 ->andWhere('level = 0')
						 ->andWhere('ordering = ?', $menuItem->ordering + 1)
						 ->execute();

				$ordering = $menuItem->ordering;
				$menuItem->ordering = $prevNode[0]->ordering;
				$menuItem->save();
				$prevNode[0]->ordering = $ordering;
				$prevNode[0]->save();
			} else {
				$nextSibling = $menuItem->getNode()->getNextSibling();
				
				if($nextSibling) {
					$menuItem->getNode()->moveAsNextSiblingOf($nextSibling);
				}
			}
		}
		
		$this->_helper->getHelper('FlashMessenger')
					->addMessage($this->view->translate('Menu item has been move successfully!'));
		return $this->_redirect($this->view->url(array(), 'navigation_menuitem_index'));
	}
	
	/**
	 * Парсинг контейнера меню
	 */
	private function _parseContainer($containers, &$menu, $depth) {
		foreach ($containers as $container) {
			if(isset($container['route'])) {
				if(isset($container['params']) && is_array($container['params'])) {
					$format_uri = $this->view->url($container['params'],$container['route']);
				} else {
					$format_uri = $this->view->url(array(),$container['route']);
				}
			} elseif(isset($container['uri'])) {
				$format_uri = $container['uri'];
			}
			$menu[$format_uri] = str_repeat('-', 2*$depth) . $container['label'];
			
			if(isset($container['pages'])) {
				$depth++;
				$this->_parseContainer($container['pages'], $menu, $depth--);
				
			}
		}
	}
	
	/**
	 * Управление публикацией
	 * @throws Zend_Controller_Action_Exception
	 */
	public function publishAction() {
		if($this->_request->isXmlHttpRequest()) {
			// Отключаем авторендеринг шаблонов
			$this->_helper->viewRenderer->setNoRender();
			// Отключаем шаблоны
			$this->_helper->layout()->disableLayout();
			
			$id = $this->_request->getParam('id',0);
			
			$menuItem = Doctrine_Core::getTable('Navigation_Model_Menuitem')->find($id);
			
			if(!$id || !$menuItem)
				throw new Zend_Controller_Action_Exception('Menu item not found!', 404);
			
			$published_array = array();	
			
			if($menuItem->getNode()->hasChildren()) {
				$children = $menuItem->getNode()->getDescendants();
				
				if($children) {
					foreach ($children as $child) {
						if($menuItem->published)
							$child->published = false;
						else
							$child->published = true;
							
						$child->save();
						
						$published_array[$child->id] = $child->published;
					}
				}
			}	
			
			if($menuItem->published) {
				$menuItem->published = false;
			} else {
				$menuItem->published = true;
			}
			
			$menuItem->save();
			
			$published_array[$menuItem->id] = $menuItem->published;
			
			$response = $this->getResponse();
			$response->appendBody(Zend_Json::encode($published_array))->setHeader('content-type', 'text/plain', true);
		} else {
			return $this->_redirect($this->view->url(array(), 'navigation_menuitem_index'));
		}
	}
	
	
}